package com.acme.bankapp.domain.email;

import java.util.*;

/*
 * Modified, with blocking limited add
 */
public class Queue {
	private LinkedList<Email> emails = new LinkedList<>();
	private boolean cancel = false;
	private static int limit = 5;
	private int used = 0;
	
	public synchronized void add(Email email) {
		while(this.used >= limit) {
			try {
				this.wait();
			} catch(InterruptedException ex) {
				throw new IllegalStateException();
			}
		}
		
		if(this.cancel) {
			return;
		}
		this.emails.add(email);
		this.notify();
		
		this.used++;
	}
	
	/*
	 * Blocks, waits if no email present
	 */
	public synchronized Email getEmail() {
		while(this.emails.isEmpty()) {
			if(this.cancel) {
				//this.notify();
				this.notifyAll();
				return null;
			}
			try {
				this.wait();
			} catch(InterruptedException ex) {
				throw new IllegalStateException();
			}
		}
		
		this.notifyAll();
		
		return this.emails.remove(0);
	}
	
	/*
	 * Blocking method
	 */
	public synchronized void close() {
		this.cancel = true;
		
		this.notifyAll();
		
		while(!this.emails.isEmpty()) {
			try {
				this.wait();
				//notify other waiting getEmail thread
				//this.notify();
				this.notifyAll();
			} catch(InterruptedException ex) {
				throw new IllegalStateException();
			}
		}
	}
}
